#include "datacenter.h"

namespace model
{
    DataCenter *DataCenter::instance = nullptr;

    DataCenter *DataCenter::getInstance()
    {
        if (instance == nullptr)
            instance = new DataCenter();
        return instance;
    }

    DataCenter::~DataCenter()
    {
        delete _myself;
        delete _friendList;
        delete _chatSessionList;
        delete _memberList;
        delete _applyList;
        delete _recentMessages;
        delete _unreadMessageCount;
        delete _searchUserResult;
        delete _searchMessageResult;
    }

    void DataCenter::initDataFile()
    {
        // 使用appdata存储文件
        QString basePath = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
        QString filePath = basePath + "/ChatClient.json";
        DEBUG() << "filePath: " << filePath;

        // 创建目录
        QDir dir;
        if (!dir.exists(basePath))
            dir.mkpath(basePath);

        // 创建文件
        // 写方式打开并写入初始内容
        QFile file(filePath);
        if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
        {
            ERROR() << "打开文件失败: " << filePath << " error: " << file.errorString();
            return;
        }
        QString data = "{\n\n}";
        file.write(data.toUtf8());
        file.close();
    }

    void DataCenter::saveDataFile()
    {
        QString filePath = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/ChatClient.json";

        QFile file(filePath);
        if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
        {
            ERROR() << "打开文件失败: " << filePath << " error: " << file.errorString();
            return;
        }

        // 按照json格式写入
        QJsonObject jsonObj;
        jsonObj["loginSessionId"] = _loginSessionId;
        QJsonObject unreadJsonObj;
        for (auto it = _unreadMessageCount->begin(); it != _unreadMessageCount->end(); it++)
        {
            unreadJsonObj[it.key()] = it.value();
        }
        jsonObj["unread"] = unreadJsonObj;

        // 写入文件
        QJsonDocument jsonDoc(jsonObj);
        QString s = jsonDoc.toJson();
        file.write(s.toUtf8());
        file.close();
    }

    void DataCenter::loadDataFile()
    {
        // 确保在加载之前针对文件进行初始化操作
        QString filePath = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/ChatClient.json";
        QFileInfo fileInfo(filePath);
        if (!fileInfo.exists())
            initDataFile();

        // 以读方式打开文件
        QFile file(filePath);
        if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
        {
            ERROR() << "打开文件失败: " << filePath << " error: " << file.errorString();
            return;
        }

        // 读取内容解析为json对象
        QJsonDocument jsonDoc = QJsonDocument::fromJson(file.readAll());
        if (jsonDoc.isNull())
        {
            ERROR() << "解析JSON文件失败, JSON文件格式有错误";
            return;
        }

        QJsonObject jsonObj = jsonDoc.object();
        this->_loginSessionId = jsonObj["loginSessionId"].toString();

        this->_unreadMessageCount->clear();
        QJsonObject jsonUnread = jsonObj["unread"].toObject();
        for (auto it = jsonUnread.begin(); it != jsonUnread.end(); it++)
        {
            this->_unreadMessageCount->insert(it.key(), it.value().toInt());
        }
    }

    void DataCenter::clearUnread(const QString &chatSessionId)
    {
        (*_unreadMessageCount)[chatSessionId] = 0;
        saveDataFile();
    }

    void DataCenter::addUnread(const QString &chatSessionId)
    {
        ++(*_unreadMessageCount)[chatSessionId];
        saveDataFile();
    }

    int DataCenter::getUnread(const QString &chatSessionId)
    {
        return (*_unreadMessageCount)[chatSessionId];
    }

    // 获取当前用户信息
    void DataCenter::getMyselfAsync()
    {
        _netClient->getMyself(_loginSessionId);
    }

    void DataCenter::resetMyself(std::shared_ptr<LYZ::GetUserInfoRsp> rsp)
    {
        if (_myself == nullptr)
            _myself = new UserInfo();
        const LYZ::UserInfo &userInfo = rsp->userInfo();
        _myself->load(userInfo);
    }

    // 获取好友列表
    void DataCenter::getFriendListAsync()
    {
        _netClient->getFriendList(_loginSessionId);
    }

    void DataCenter::resetFriendList(std::shared_ptr<LYZ::GetFriendListRsp> rsp)
    {
        if (_friendList == nullptr)
            _friendList = new QList<UserInfo>();
        _friendList->clear();
        for (auto &u : rsp->friendList())
        {
            UserInfo userInfo;
            userInfo.load(u);
            _friendList->push_back(userInfo);
        }
    }

    // 获取会话列表
    void DataCenter::getChatSessionListAsync()
    {
        _netClient->getChatSessionList(_loginSessionId);
    }

    void DataCenter::resetChatSessionList(std::shared_ptr<LYZ::GetChatSessionListRsp> rsp)
    {
        if (_chatSessionList == nullptr)
            _chatSessionList = new QList<ChatSessionInfo>();
        _chatSessionList->clear();
        for (auto &c : rsp->chatSessionInfoList())
        {
            ChatSessionInfo chatSessionInfo;
            chatSessionInfo.load(c);
            _chatSessionList->push_back(chatSessionInfo);
        }
    }

    // 获取申请列表
    void DataCenter::getApplyListAsync()
    {
        _netClient->getApplyList(_loginSessionId);
    }

    void DataCenter::resetApplyList(std::shared_ptr<LYZ::GetPendingFriendEventListRsp> rsp)
    {
        if (_applyList == nullptr)
            _applyList = new QList<UserInfo>();
        _applyList->clear();
        for (auto &u : rsp->event())
        {
            UserInfo userInfo;
            userInfo.load(u.sender());
            _applyList->push_back(userInfo);
        }
    }

    // 获取最近消息
    void DataCenter::getRecentMsgAsync(const QString &chatSessionId, bool updateUI)
    {
        _netClient->getRecentMsg(_loginSessionId, chatSessionId, updateUI);
    }

    QList<MessageInfo> *DataCenter::getRecentMsg(const QString &chatSessionId)
    {
        if (!_recentMessages->contains(chatSessionId))
            return nullptr;
        return &(*_recentMessages)[chatSessionId];
    }

    void DataCenter::resetRecentMsgList(const QString &chatSessionId, std::shared_ptr<LYZ::GetRecentMsgRsp> rsp)
    {
        QList<MessageInfo> &msgList = (*_recentMessages)[chatSessionId];
        msgList.clear();

        for (auto &m : rsp->msgList())
        {
            MessageInfo msgInfo;
            msgInfo.load(m);
            msgList.push_back(msgInfo);
        }
    }

    // 发送文本消息
    void DataCenter::sentTextMessageAsync(const QString &chatSessionId, const QString &content)
    {
        _netClient->sentMessage(_loginSessionId, chatSessionId, MessageType::STRING_TYPE, content.toUtf8());
    }

    // 修改用户昵称
    void DataCenter::changeNicknameAsync(const QString &newName)
    {
        _netClient->changeNickname(_loginSessionId, newName);
    }

    void DataCenter::resetNickname(const QString &newName)
    {
        if (_myself == nullptr)
            return;
        _myself->_nickname = newName;
    }

    // 通过id查询会话信息
    ChatSessionInfo *DataCenter::findChatSessionById(const QString &chatSessionId)
    {
        if (_chatSessionList == nullptr)
            return nullptr;
        for (auto & c : *_chatSessionList)
        {
            if (c._chat_session_id == chatSessionId)
                return &c;
        }
        return nullptr;
    }

    ChatSessionInfo *DataCenter::findChatSessionByUserId(const QString &userId)
    {
        if (_chatSessionList == nullptr)
            return nullptr;
        for (auto & c : *_chatSessionList)
        {
            if (c._user_id == userId)
                return &c;
        }
        return nullptr;
    }

    void DataCenter::topChatSessionInfo(const ChatSessionInfo &chatSessionInfo)
    {
        if (_chatSessionList == nullptr)
            return;
        auto it = _chatSessionList->begin();
        for (; it != _chatSessionList->end(); it++)
        {
            if (it->_chat_session_id == chatSessionInfo._chat_session_id)
                break;
        }
        if (it == _chatSessionList->end())
            return;

        ChatSessionInfo backUp = chatSessionInfo;
        _chatSessionList->erase(it);

        _chatSessionList->push_front(backUp);
    }

    void DataCenter::addMessage(MessageInfo msg)
    {
        (*_recentMessages)[msg._chat_session_id].push_back(msg);
    }

    void DataCenter::updateChatSessionLastMsg(const QString &chatSessionId, const MessageInfo &msgInfo)
    {
        for (int i = 0; i < _chatSessionList->size(); i++)
        {
            if ((*_chatSessionList)[i]._chat_session_id == chatSessionId)
            {
                (*_chatSessionList)[i]._last_message = msgInfo;
                return;
            }
        }
    }

    DataCenter::DataCenter()
    {
        _memberList = new QHash<QString, QList<UserInfo>>();
        _recentMessages = new QHash<QString, QList<MessageInfo>>();
        _unreadMessageCount = new QHash<QString, int>();
        _netClient = new network::NetClient(this);

        loadDataFile();
    }
}


